package com.cjmust.array;

public class Array {

    // 数据容器
    private int[] data;
    /**
     * 数组的有效数据数量
     * size在数组初始化的默认值是0
     */
    private int size;

    /**
     * 构造函数
     * @param capacity 容量
     */
    public Array(int capacity){
        data = new int[capacity];
        size = 0;
    }

    /**
     * 默认无参构造函数, 容量为10
     */
    public Array(){
        this(10);
    }

    /**
     * 获取数组元素个数
     * @return
     */
    public int getSize(){
        return size;
    }

    /**
     * 获取数组容量
     * @return
     */
    public int getCapacity(){
        return data.length;
    }

    /**
     * 判断数组是否为空
     * @return
     */
    public boolean isEmpty(){
        return size==0;
    }

    /**
     * 向数组头部添加新的元素
     */
    public void addFirst(int e){
        add(0 , e);
    }

    /**
     * 向数组末尾添加元素
     * 最好的方式就是向数组的末尾添加元素
     * 只需要每次给data[size]赋值, 然后size++即可, size总是末尾
     */
    public void addLast(int e){
        add(size, e);
    }

    /**
     * 向数组中的指定位置添加元素
     * 比如往 1 的位置添加元素, 那么需要将 1 位置开始之后的元素全部后移一位
     * 将 1 位置腾空, 将目标元素插入其中
     * size ++
     */
    public void add(int index, int e) {
        if(size == data.length){
            throw new IllegalArgumentException("Add failed. Array is FULL");
        }
        // 校验index是否合法
        if(index < 0 || index > size){
            throw new IllegalArgumentException("Add failed. Require index >=0 and index <= size");
        }
        // 开始移动元素, 腾空位置, index位置的元素全部后移一位
        for (int i = size - 1 ; i >= index ; i--){
            data[i + 1]=data[i];
        }

        data[index] = e;

        size ++ ;
    }

    /**
     * 获取 index 位置的元素
     */
    public int get(int index){
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("get failed. index is illegal");
        }
        return data[index];
    }

    /**
     * 更新指定位置的数组元素
     */
    public void set(int index, int e){
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("get failed. index is illegal");
        }
        data[index] = e;
    }

    /**
     * 判断数组中是否存在传入的元素e
     */
    public boolean contains(int e){
        for(int i=0 ; i<size ; i++){
            if(data[i] == e){
                return true;
            }
        }
        return false;
    }

    /**
     * 查找元素e, 若存在, 则返回其索引, 若不存在, 则返回-1
     */
    public int find(int e){
        for(int i=0 ; i<size ; i++){
            if(data[i] == e){
                return i;
            }
        }
        return -1;
    }

    /**
     * 删除指定位置元素
     * 指定位置元素移除, 后面元素依次向前
     * 给最后一个空出的元素赋值null
     * 维护 size--
     * @return removing target
     */
    public int remove(int index){
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("Remove failed. Index error, need index>0 and index<size ; maybe the size of array is 0");
        }
        int removingTarget = data[index];
        for (int i = index ; i < size - 1 ; i++){
            data[i] = data[i+1];
        }
        data[size - 1] = 0;
        size --;
        return removingTarget;
    }

    /**
     * 移除第一个元素
     * @return target
     */
    public int removeFirst(){
        return remove(0);
    }

    /**
     * 移除数组最后一个元素
     */
    public int removeLast(){
        return remove(size - 1);
    }

    /**
     * 移除指定元素
     * 组合之前的方法即可实现
     * 1. 调用find获取索引
     * 2. 调用remove移除元素
     * @param e
     * @TODO 此方法只会删除找到的第一个元素, 可以新增一个removeAllElement方法
     */
    public void removeElement(int e){
        int index = find(e);
        remove(index);
    }

    /**
     * override toString
     * @return
     */
    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        res.append(String.format("Array : size = %d , capacity = %d\n", size , data.length));
        res.append("[");
        for (int i = 0 ; i < size ; i++){
            res.append(data[i]);
            if( i != size-1 ){
                res.append(", ");
            }
        }
        res.append("]");
        return res.toString();
    }
}
